﻿namespace Red.Toolkit.Profiler.Drawing
{
    public class TimelineParams
    {
        public const double ZoomFactor = 0.8;
        public const double MaxZoom = 1.0e9;      // 1 nanosecond / pixel
        public const double MinZoom = 1.0 / 60.0; // 1 min / pixel

        public delegate void OnDraw();
        public OnDraw OnDrawDelegate;

        private double _secondsPerPixel;
        private double _pixelsPerSecond;  // pixels per second (zoom)
        public double TimeOffset; // offset in seconds (time at X=0)
        public double YOffset;    // Y-axis offset

        public double TimeRangeStart;
        public double TimeRangeEnd;

        public double CursorPos; // (in seconds)

        public TimelineParams()
        {
            CursorPos = 0.0;
            _pixelsPerSecond = 100.0;
            _secondsPerPixel = 1.0 / _pixelsPerSecond;
            TimeOffset = 0.0;
            YOffset = 0.0;

            TimeRangeStart = 0.0;
            TimeRangeEnd = 3000.0;
        }

        public void Zoom( int delta )
        {
            if ( delta > 0 )
            {
                _pixelsPerSecond /= ZoomFactor;
                if ( _pixelsPerSecond > MaxZoom )
                    _pixelsPerSecond = MaxZoom;
            }
            else if ( delta < 0 )
            {
                _pixelsPerSecond *= ZoomFactor;
                if ( _pixelsPerSecond < MinZoom )
                    _pixelsPerSecond = MinZoom;
            }

            _secondsPerPixel = 1.0 / _pixelsPerSecond;
        }

        public void ZoomAtTime( int delta, double centerTime )
        {
            double canvasX = TimeToCanvasX( centerTime );
            Zoom( delta );
            TimeOffset = centerTime - (canvasX * SecondsPerPixel);
        }

        public void ZoomAtCanvasX( int delta, double canvasCenterX )
        {
            double timeAtPoint = CanvasXToTime( canvasCenterX );
            Zoom( delta );
            TimeOffset = timeAtPoint - (canvasCenterX * SecondsPerPixel);
        }

        public double TimeToCanvasX( double time )
        {
            return (time - TimeOffset) * PixelsPerSecond;
        }

        public double CanvasXToTime( double x )
        {
            return x * SecondsPerPixel + TimeOffset;
        }

        public double SecondsPerPixel
        {
            get
            {
                return _secondsPerPixel;
            }

            set
            {
                _secondsPerPixel = value;
                _pixelsPerSecond = 1.0 / _secondsPerPixel;
            }
        }

        public double PixelsPerSecond
        {
            get
            {
                return _pixelsPerSecond;
            }

            set
            {
                _pixelsPerSecond = value;
                _secondsPerPixel = 1.0 / _pixelsPerSecond;
            }
        }
    }
}
